package System;

import java.io.IOException;

import javax.swing.JOptionPane;

import BaseClasses.PracticalExam;
import BaseClasses.Question;
import BaseClasses.Subject;
import BaseClasses.User;

import ocsf.server.AbstractServer;
import ocsf.server.ConnectionToClient;
import System.SysMode;
import System.Server;
import System.SystemObject;
import System.DataBase;


/**
 * @author Baruch Cohen 
 * @author Nir Bazak
 * @author Gil klebanov
 * @author Ivgeny kritshul
 * @version June 2012
 */
public class EchoServer extends AbstractServer {
	/**The data base variable**/
	private DataBase db;
	
	//**Constructors**//
	/**
	 * The default port to listen on
	 */
	public EchoServer(int port,String dbPass) throws Exception{
		super(port);
		db = new DataBase(dbPass);
	}

	/**
	 * send a message to client
	 * 
	 * @param client the client to send the msg to
	 * @param msg the message sent to client
	 */
	protected  void sendMsgToClient(ConnectionToClient client, Object msg)
	{
		try { client.sendToClient(msg);}
		catch (IOException ex) {display("sendMsgToClient - IO exception");}
	}

	/**
	 * This method overrides the one in the superclass. 
	 * Called when the server starts listening for connections.
	 */
	protected void serverStarted() 
	{
		JOptionPane.showMessageDialog(null, "Server Started", "System Message", JOptionPane.INFORMATION_MESSAGE);
		display("Server listening for connections on port " + getPort());
	}

	public static void display(String msg) {
		Server.serverOn.textArea.append("\n" + msg);
	}
	/**
	 * This method overrides the one in the superclass.  Called
	 * when the server stops listening for connections.
	 */
	protected void serverStopped() {display("Server has stopped listening for connections.");}

	/**
	 * This method handles any messages received from the client.
	 * every case represents a different object handling.
	 * @param msg The message received from the client.
	 * @param client The connection from which the message is originated.
	 */
	public synchronized void handleMessageFromClient(Object msg, ConnectionToClient client)
	{
		SystemObject sysObj = (SystemObject) msg;
		switch(sysObj.getMode())
		{
		case User_Login:
		{
			Object[] obj;
			try{
				db.setConnection();
				obj = (Object[]) db.getLogin((User)sysObj.getObj() );
				if (obj != null && obj[0] instanceof User)
					sysObj.setMode(SysMode.OK);  
				else
					sysObj.setMode(SysMode.NOT_OK);
				sysObj.setObj(obj);
			}
			catch(Exception e)
			{
				sysObj.setObj(e.getMessage());
				sysObj.setMode(SysMode.ConnFail);
			}
			try{client.sendToClient(sysObj); db.closeConnection();}
			catch(Exception e)
			{
				display("Can't send message to client, server will close " + e.getMessage());
				System.exit(1);
			}
			break;
		}
		case AddQuestion:
		{
			int flag;
			try{
				db.setConnection();
				flag = (int) db.insertQuestion((Question)sysObj.getObj() );
				if (flag != 0)
					sysObj.setMode(SysMode.OK);  
				else
					sysObj.setMode(SysMode.NOT_OK);
				sysObj.setObj(flag);
			}
			catch(Exception e)
			{
				sysObj.setObj(e.getMessage());
				sysObj.setMode(SysMode.ConnFail);
			}
			try{client.sendToClient(sysObj); db.closeConnection();}
			catch(Exception e)
			{
				display("Can't send message to client, server will close " + e.getMessage());
				System.exit(1);
			}
			break;
		}	
		
		case RemoveQuestion:
			Object[] obj;
			try{
				db.setConnection();
				obj = (Object[]) db.DeleteQuestion((Question)sysObj.getObj() );
				if (obj != null && obj[0] instanceof Question)
					sysObj.setMode(SysMode.OK);  
				else
					sysObj.setMode(SysMode.NOT_OK);
				sysObj.setObj(obj);
			}
			catch(Exception e)
			{
				sysObj.setObj(e.getMessage());
				sysObj.setMode(SysMode.ConnFail);
			}
			try{client.sendToClient(sysObj); db.closeConnection();}
			catch(Exception e)
			{
				display("Can't send message to client, server will close " + e.getMessage());
				System.exit(1);
			}
			break;
			/**
			 * Change Parent Block
			 */
			case changParaentBlock:
			{
				try
				{
					db.setConnection();
					sysObj = db.changParaentBlock(sysObj.getObj());
				}
				catch(Exception ex)
				{
					sysObj.setMode(SysMode.NOT_OK);
					sysObj.setObj(ex.getMessage());
					this.sendMsgToClient(client, sysObj);
				}
				try
				{
					db.closeConnection(); 
					client.sendToClient(sysObj);
				}
				catch(Exception e)
				{
					display("Can't send message to client, server will close "+ e.getMessage());
					System.exit(1);
				}
				break;
			}		
	case getQuestions:
		try{
		db.setConnection();
		SystemObject object = db.getQuestions();
		if (object == null)
		{
			object = new SystemObject();
			object.setMode(SysMode.NOT_OK);
		}
		client.sendToClient(object); db.closeConnection();}
		catch(Exception e)
		{
			display("Can't send message to client, server will close " + e.getMessage());
			System.exit(1);
		}
		break;
	
	case getQuestionsbysid:
		
		Question result;
		try {
			db.setConnection();
			 SystemObject sys= db.getQuestionsbysid((Subject) sysObj.getObj());
			 
			if(sys == null)
			{
				sys=new SystemObject();
				sys.setMode(SysMode.NOT_OK);
			}
			client.sendToClient(sys); db.closeConnection();
			}
		catch(Exception e)
		{
			display("Can't send message to client, server will close " + e.getMessage());
			System.exit(1);
		}
		break;
		
	case getExam:
		try{
		db.setConnection();
		SystemObject object = db.getExam();
		if (object == null)
		{
			object = new SystemObject();
			object.setMode(SysMode.NOT_OK);
		}
		client.sendToClient(object); db.closeConnection();}
		catch(Exception e)
		{
			display("Can't send message to client, server will close " + e.getMessage());
			System.exit(1);
		}
		break;

	case getSubject:
	try{
	db.setConnection();
	SystemObject object = db.getSubject((User) sysObj.getObj());
	if (object == null)
	{
		object = new SystemObject();
		object.setMode(SysMode.NOT_OK);
	}
	client.sendToClient(object); db.closeConnection();}
	catch(Exception e)
	{
		display("Can't send message to client, server will close " + e.getMessage());
		System.exit(1);
	}
	break;
		
	case deleteExam:
		Object[] object;
		try{
			db.setConnection();
			object = (Object[]) db.DeleteExam((PracticalExam) sysObj.getObj() );
			if (object != null && object[0] instanceof PracticalExam)
				sysObj.setMode(SysMode.OK);  
			else
				sysObj.setMode(SysMode.NOT_OK);
			sysObj.setObj(object);
		}
		catch(Exception e)
		{
			sysObj.setObj(e.getMessage());
			sysObj.setMode(SysMode.ConnFail);
		}
		try{client.sendToClient(sysObj); db.closeConnection();}
		catch(Exception e)
		{
			display("Can't send message to client, server will close " + e.getMessage());
			System.exit(1);
		}
		break;

	case LogOut:
	{
		SysMode result1;
		try
		{
			db.setConnection();
			sysObj.setMode(result1 = db.LogOut((User) sysObj.getObj()));
			if (result1 == SysMode.NOT_OK)
				sysObj.setObj(new String("Can't Log You out, check with your system Admin. Good Bye"));
			else
				sysObj.setObj(new String("Good Bye"));
		}
		catch(Exception ex)
		{
			sysObj.setObj(new String("Connection To Data Base Failed, Check with Your system Admin"));
			sysObj.setMode(SysMode.ConnFail);
		}
		try{client.sendToClient(sysObj);}
		catch(Exception e)
		{
			display("Can't send message to client, server will close " + e.getMessage());
			System.exit(1);
		}
		break;
	}	
	case AddExam:
	{
		int flag;
		try{
			db.setConnection();
			flag = (int) db.AddExam((PracticalExam) sysObj.getObj());
			if (flag != 0)
				sysObj.setMode(SysMode.OK);  
			else
				sysObj.setMode(SysMode.NOT_OK);
			sysObj.setObj(flag);
		}
		catch(Exception e)
		{
			sysObj.setObj(e.getMessage());
			sysObj.setMode(SysMode.ConnFail);
		}
		try{client.sendToClient(sysObj); db.closeConnection();}
		catch(Exception e)
		{
			display("Can't send message to client, server will close " + e.getMessage());
			System.exit(1);
		}
		break;
	}
}
}
}






